<?php
namespace Swocloud;

use Swocloud\Server;
use Swoole\WebSocket\Server as SwooleServer;
use Redis;
use Swoole\Http\Request;
use Swoole\Http\Response;

/**
 * 1. 检测IM-server的存活状态
 * 2. 支持权限认证
 * 3. 根据服务器的状态，按照一定的算法，计算出该客户端连接到哪台IM-server，返回给客户端，客户端再去连接到对应的服务端,保存客户端与IM-server的路由关系
 * 4. 如果 IM-server宕机，会自动从Redis中当中剔除
 * 5. IM-server上线后连接到Route，自动加 入Redis(im-server ip:port)
 * 6. 可以接受来自PHP代码、C++程序、Java程序的消息请求，转发给用户所在的IM-server
 * 7. 缓存服务器地址，多次查询redis
 *
 * 是一个websocket
 */
class Route extends Server
{
    protected $cacheKey = 'im_server';

    protected $redis;

    protected $dispatcher = null;

    public function createServer()
    {
        $this->swooleServer = new SwooleServer($this->host, $this->port);

        dd("route-server {$this->host}:{$this->port}");
    }

    public function initEvents()
    {
        $this->setEvent('sub', [
            'open'    => 'onOpen',
            'message' => 'onMessage',
            'close'   => 'onClose',
            'request' => 'onRequest',
        ]);
    }

    public function onWorkerStart($server, $workerId)
    {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }

    public function onOpen()
    {
        dd('open');
    }

    public function onMessage(SwooleServer $server, $frame)
    {
        $data = json_decode($frame->data, true);
        $fd = $frame->fd;

        if (isset($data['aaa'])) {
            return;
        }

        // 执行对应方法
        $this->getDispatcher()->{$data['method']}($this, $server, $fd, $data);
    }

    public function onClose($server, $fd)
    {
    }

    public function onRequest(Request $request, Response $response)
    {
        if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
            $response->end();
            return;
        }
        
        // 解决跨域
        $response->header('Access-Control-Allow-Origin', "*");
        $response->header('Access-Control-Allow-Methods', "GET,POST");

        // 获取请求参数
        // [
        //     'method' => 'login',
        //     'name' => 'user1',
        //     'pass' => 'pass1'
        // ]
        
        $this->getDispatcher()->{$request->post['method']}($this, $request, $response);
    }

    /**
     * 获取业务处理类
     * @return mixed|Dispatcher 
     */
    protected function getDispatcher()
    {
        if ($this->dispatcher === null) {
            $this->dispatcher = new Dispatcher($this->redis);
        }

        return $this->dispatcher;
    }

    /**
     * 获取cacheKey
     * @return mixed 
     */
    public function getCacheKey()
    {
        return $this->cacheKey;
    }

    /**
     * 获取imserver所选择的算法
     * @return mixed 
     */
    public function getArithmetic()
    {
        if (!isset($this->config['arithmetic'])) {
            $this->config['arithmetic'] = 'round';
        }

        return $this->config['arithmetic'];
    }
}
